document.addEventListener('DOMContentLoaded', () => {
    const gameBoard = document.getElementById('game-board');
    const currentScore = document.getElementById('current-score');
    const bestScore = document.getElementById('best-score');
    
    let board = [];
    let score = 0;
    let bestScoreValue = localStorage.getItem('bestScore') || 0;
    
    bestScore.textContent = bestScoreValue;
    
    // Initialize the game board
    function initBoard() {
        board = [];
        gameBoard.innerHTML = '';
        
        for (let i = 0; i < 4; i++) {
            board[i] = [];
            for (let j = 0; j < 4; j++) {
                board[i][j] = 0;
                const tile = document.createElement('div');
                tile.classList.add('tile');
                tile.id = `tile-${i}-${j}`;
                gameBoard.appendChild(tile);
            }
        }
        
        // Add two initial tiles
        addNewTile();
        addNewTile();
        
        score = 0;
        currentScore.textContent = score;
    }
    
    // Start a new game
    window.startGame = function() {
        score = 0;
        currentScore.textContent = score;
        initBoard();
    };
    
    // Add a new tile (2 or 4) to a random empty position
    function addNewTile() {
        const emptyTiles = [];
        
        for (let i = 0; i < 4; i++) {
            for (let j = 0; j < 4; j++) {
                if (board[i][j] === 0) {
                    emptyTiles.push({i, j});
                }
            }
        }
        
        if (emptyTiles.length === 0) return;
        
        const {i, j} = emptyTiles[Math.floor(Math.random() * emptyTiles.length)];
        board[i][j] = Math.random() < 0.9 ? 2 : 4;
        updateTileDisplay(i, j);
    }
    
    // Update the display of a specific tile
    function updateTileDisplay(i, j) {
        const tile = document.getElementById(`tile-${i}-${j}`);
        tile.textContent = board[i][j] === 0 ? '' : board[i][j];
        tile.className = 'tile';
        
        if (board[i][j] !== 0) {
            tile.classList.add(`tile-${board[i][j]}`);
        }
    }
    
    // Handle keyboard input
    document.addEventListener('keydown', handleKeyPress);
    
    function handleKeyPress(e) {
        if (e.key === 'ArrowUp' || e.key === 'ArrowDown' || 
            e.key === 'ArrowLeft' || e.key === 'ArrowRight' ||
            e.key === 'w' || e.key === 's' || 
            e.key === 'a' || e.key === 'd') {
            // Map WASD keys to arrow keys for consistency
            const keyMap = {
                'w': 'ArrowUp',
                's': 'ArrowDown',
                'a': 'ArrowLeft',
                'd': 'ArrowRight'
            };
            
            moveTiles(keyMap[e.key] || e.key);
        }
    }
    
    // Move and merge tiles in the specified direction
    function moveTiles(direction) {
        let moved = false;
        
        // Helper function to slide and merge a row/column
        function slideAndMerge(rowOrCol) {
            const result = [];
            let prev = null;
            
            // Remove zeros (empty cells)
            const nonZero = rowOrCol.filter(val => val !== 0);
            
            // Merge adjacent tiles with the same value
            for (let i = 0; i < nonZero.length; i++) {
                if (prev === null) {
                    prev = nonZero[i];
                } else if (nonZero[i] === prev) {
                    result.push(prev * 2);
                    score += prev * 2;
                    prev = null;
                    moved = true;
                } else {
                    result.push(prev);
                    prev = nonZero[i];
                }
            }
            
            if (prev !== null) {
                result.push(prev);
            }
            
            // Fill the remaining spaces with zeros
            while (result.length < 4) {
                result.push(0);
            }
            
            return result;
        }
        
        let newBoard = [];
        
        switch (direction) {
            case 'ArrowLeft':
                for (let i = 0; i < 4; i++) {
                    const newRow = slideAndMerge(board[i]);
                    if (newRow.some((val, j) => val !== board[i][j])) moved = true;
                    newBoard[i] = newRow;
                }
                break;
            
            case 'ArrowRight':
                for (let i = 0; i < 4; i++) {
                    const reversedRow = board[i].slice().reverse();
                    const newReversedRow = slideAndMerge(reversedRow);
                    const newRow = newReversedRow.slice().reverse();
                    if (newRow.some((val, j) => val !== board[i][j])) moved = true;
                    newBoard[i] = newRow;
                }
                break;
            
            case 'ArrowUp':
                for (let j = 0; j < 4; j++) {
                    const col = [];
                    for (let i = 0; i < 4; i++) {
                        col.push(board[i][j]);
                    }
                    
                    const newCol = slideAndMerge(col);
                    
                    if (newCol.some((val, i) => val !== board[i][j])) moved = true;
                    
                    for (let i = 0; i < 4; i++) {
                        if (!newBoard[i]) newBoard[i] = [];
                        newBoard[i][j] = newCol[i];
                    }
                }
                break;
            
            case 'ArrowDown':
                for (let j = 0; j < 4; j++) {
                    const col = [];
                    for (let i = 0; i < 4; i++) {
                        col.push(board[i][j]);
                    }
                    
                    const reversedCol = col.slice().reverse();
                    const newReversedCol = slideAndMerge(reversedCol);
                    const newCol = newReversedCol.slice().reverse();
                    
                    if (newCol.some((val, i) => val !== board[i][j])) moved = true;
                    
                    for (let i = 0; i < 4; i++) {
                        if (!newBoard[i]) newBoard[i] = [];
                        newBoard[i][j] = newCol[i];
                    }
                }
                break;
        }
        
        if (moved) {
            board = newBoard;
            currentScore.textContent = score;
            
            if (score > bestScoreValue) {
                bestScoreValue = score;
                bestScore.textContent = score;
                localStorage.setItem('bestScore', score);
            }
            
            updateBoardDisplay();
            addNewTile();
            
            if (isGameOver()) {
                setTimeout(() => {
                    alert('游戏结束!');
                }, 100);
            }
        }
    }
    
    // Update the display of all tiles
    function updateBoardDisplay() {
        for (let i = 0; i < 4; i++) {
            for (let j = 0; j < 4; j++) {
                updateTileDisplay(i, j);
            }
        }
    }
    
    // Check if the game is over (no more possible moves)
    function isGameOver() {
        // Check if there are any empty cells
        for (let i = 0; i < 4; i++) {
            for (let j = 0; j < 4; j++) {
                if (board[i][j] === 0) {
                    return false;
                }
            }
        }
        
        // Check for possible merges in all directions
        for (let i = 0; i < 4; i++) {
            for (let j = 0; j < 4; j++) {
                const current = board[i][j];
                
                // Check right neighbor
                if (j < 3 && current === board[i][j + 1]) {
                    return false;
                }
                
                // Check down neighbor
                if (i < 3 && current === board[i + 1][j]) {
                    return false;
                }
            }
        }
        
        return true;
    }
});